package murraco.exception;

import murraco.common.Result;
import murraco.common.ResultCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;


@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 处理自定义异常
     * @param ex
     * @return //
     */
    @ExceptionHandler({MissingServletRequestParameterException.class, BusinessException.class})
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result handleRuntimeException(BusinessException ex) {
        //logger.info("catch BusinessException:"+ ex.toString());
        //不适合查询问题所在位置，所以必须打出所有堆栈
        ex.printStackTrace();
        return Result.failure(ex.getCode());
    }

    @ExceptionHandler(value = {MethodArgumentNotValidException.class, BindException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)	//400
    protected Result addValidationError(Exception e){
        List errorList=new ArrayList();
        List<ObjectError> errors = new LinkedList();
        if(e instanceof MethodArgumentNotValidException){
            MethodArgumentNotValidException validException = (MethodArgumentNotValidException)e;
            errors = validException.getBindingResult().getAllErrors();
        }else{
            BindException validException = (BindException)e;
            errors = validException.getBindingResult().getAllErrors();
        }

        for(ObjectError fieldError:errors){
            errorList.add(fieldError.getDefaultMessage());
        }

        return Result.failure( ResultCode.DATA_IS_WRONG,errorList);

    }

    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)	//400
    protected Result handleConstraintViolationException(ConstraintViolationException e){
        List errorList=new ArrayList();

        for(ConstraintViolation<?> constraintViolation:e.getConstraintViolations()){
            errorList.add(constraintViolation.getMessage());
        }

        return Result.failure(ResultCode.DATA_IS_WRONG,errorList);

    }
}
